package com.slipper.common.tree;

import java.io.Serializable;
import java.util.Set;
import java.util.TreeSet;

public class Node implements java.io.Serializable, Comparable<Node> {
    private static final long serialVersionUID = 1L;

    private Serializable id; // 节点id
    private Serializable pid; // 父节点id
    private Integer level = 0; // 当前级别
    private String type; // 节点类型
    private String text; // 节点名称
    private String levelText; // 节点级联名称
    private String href; // 节点URL
    private Integer orderBy; // 排序
    private Object data; // 节点数据对象
    private boolean disable = false; // 是否有效
    private boolean lazy = false; // 是否懒加载
    private boolean leaf = true; // 是否叶节点
    private Set<Node> children = new TreeSet<>(); // 子节点
    private String sortType = "asc";

    public String getSortType() {
        return sortType;
    }

    public void setSortType(String sortType) {
        this.sortType = sortType;
    }

    public Node(Serializable pid) {
        this.pid = pid;
    }

    public Node(Serializable id, String text, String href) {
        this(id, null, text, null, href, null, "asc", false, null);
    }

    public Node(Serializable id, Serializable pid, String text, String href) {
        this(id, pid, text, null, href, null, "asc", false, null);
    }

    public Node(
            Serializable id,
            Serializable pid,
            String text,
            String type,
            String href,
            Integer orderBy,
            String sortType,
            boolean disabled,
            Object data) {
        this.id = id;
        this.pid = pid;
        this.text = text;
        this.type = type;
        this.href = href;
        this.orderBy = orderBy;
        this.sortType = sortType;
        this.disable = disabled;
        this.data = data;
    }

    /**
     * 添加子节点
     */
    public void addChildren(Node node) {
        node.level = this.level + 1;
        node.setLevelText((this.levelText == null ? "" : this.levelText + "/") + node.getText());
        this.children.add(node);
        this.setLeaf(true);
    }

    public Serializable getId() {
        return this.id;
    }

    public Serializable getPid() {
        return this.pid;
    }

    public void setPid(Serializable pid) {
        this.pid = pid;
    }

    public void setId(Serializable id) {
        this.id = id;
    }

    public Integer getLevel() {
        return level;
    }

    public void setLevel(Integer level) {
        this.level = level;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    public String getText() {
        return this.text;
    }

    public void setText(String text) {
        this.text = text;
    }

    public String getLevelText() {
        return levelText;
    }

    public void setLevelText(String levelText) {
        this.levelText = levelText;
    }

    public String getHref() {
        return this.href;
    }

    public void setHref(String href) {
        this.href = href;
    }

    public Set<Node> getChildren() {
        return this.children;
    }

    public void setChildren(Set<Node> children) {
        this.children = children;
        this.setLeaf(this.children == null || this.children.isEmpty());
    }

    public Object getData() {
        return this.data;
    }

    public void setData(Object data) {
        this.data = data;
    }

    public boolean isLazy() {
        return lazy;
    }

    public void setLazy(boolean lazy) {
        this.lazy = lazy;
        this.setLeaf(!this.lazy);
    }

    public boolean isLeaf() {
        return leaf;
    }

    public void setLeaf(boolean leaf) {
        this.leaf = leaf;
    }

    public Integer getOrderBy() {
        return this.orderBy;
    }

    public void setOrderBy(Integer orderBy) {
        this.orderBy = orderBy;
    }

    public boolean isDisable() {
        return disable;
    }

    public void setDisable(boolean disabled) {
        this.disable = disabled;
    }

    public boolean isPenultimate() {
        return !this.isLeaf() && (this.children.iterator().next().isLeaf());
    }

    public int penultimateChildrenCount() {
        int count = 0;
        for (Node node : this.children) {
            count += node.penultimateChildrenCount();
        }
        return this.isPenultimate() ? 1 : count;
    }

    public int allChildrenCountWithLeaf() {
        int count = 0;
        for (Node node : this.children) {
            count += node.allChildrenCountWithLeaf();
        }
        return count + this.children.size();
    }

    /**
     * @see java.lang.Comparable#compareTo(java.lang.Object)
     */
    public int compareTo(Node node) {
        if (this.orderBy == null
                && node.getOrderBy() == null
                && this.text != null
                && node.getText() != null) {
            String text1 = this.text;
            String text2 = node.getText();
            return text1.compareTo(text2);
        }
        if (this.orderBy != null && node.getOrderBy() != null) {
            if (this.orderBy.intValue() == node.getOrderBy().intValue()) {
                return 1;
            }
            if (node.getSortType() != null && "desc".equals(node.getSortType())) {
                //降序
                return node.getOrderBy().compareTo(this.orderBy);
            } else {
                return this.orderBy.compareTo(node.getOrderBy());
            }
        }
        return 1;
    }
}
